#!/usr/bin/python3
# -*- coding: utf-8 -*-

"""
# @version: v1.0
# @author : wlisingle
# @Email : 19688513@qq.com
# @Project : g-carbon-bio
# @File : historical_stockdata_fetcher.py
# @Software: PyCharm
# @time: 2025/2/17 19:35
# @description : 
"""

import akshare as ak
import time
from service.models.stock_historical_data import StockHistoricalData


class HistoricalStockDataFetcher:
    def fetch_stock_data(self, symbol, start_date, end_date):
        """
        获取股票历史数据
        :return: 包含股票历史数据的列表
        """
        # 添加延迟时间，避免频繁请求
        time.sleep(0.1)

        # 设置重试次数和计数器
        max_retries = 3
        retry_count = 0

        stock_historical_df = None  # 初始化 DataFrame

        while retry_count < max_retries:
            try:
                stock_historical_df = ak.stock_zh_a_hist(
                    symbol=symbol,
                    period="daily",
                    start_date=start_date,
                    end_date=end_date,
                    adjust="qfq"
                )
                print(f"历史数据成功获取: {symbol}")
                break  # 退出循环，因为成功获取数据
            except Exception as e:
                print(f"获取数据时出错: {e}")
                retry_count += 1
                if retry_count < max_retries:
                    print("尝试重新获取数据...")
                    time.sleep(1)  # 等待1秒后重试
                else:
                    print("已达到最大重试次数，无法获取数据")

        if stock_historical_df is None or stock_historical_df.empty:
            raise ValueError("无法获取股票历史数据，DataFrame 为空或未成功获取。")

        historical_data_list = []
        for index, row in stock_historical_df.iterrows():
            historical_data = StockHistoricalData(
                date=row['日期'],
                stock_code=row['股票代码'],
                open_price=row['开盘'],
                close_price=row['收盘'],
                high_price=row['最高'],
                low_price=row['最低'],
                volume=row['成交量'],
                turnover=row['成交额'],
                amplitude=row['振幅'],
                change_rate=row['涨跌幅'],
                change_amount=row['涨跌额'],
                turnover_rate=row['换手率']
            )
            historical_data_list.append(historical_data)

        return historical_data_list

    def calculate_amplitudes(self, historical_data_list, latest_price):
        """
        计算区间内的振幅

        :param historical_data_list: 历史数据列表，包含12天的数据
        :param latest_price: 最新价格，用于计算振幅
        :return: 振幅
        """
        if not historical_data_list:
            return 0  # 如果历史数据列表为空，返回0

        # 提取历史数据列表中的最高价和最低价
        high_price = max(data.high_price for data in historical_data_list)
        low_price = min(data.low_price for data in historical_data_list)

        # 振幅 = (区间内最高价 - 区间内最低价) / 最新价格 × 100%
        amplitudes = (high_price - low_price) / latest_price * 100 if latest_price != 0 else 0
        # 保留两位小数
        return round(amplitudes, 2)

    def get_days_before(self, historical_data_list, days):
        """
        获取前几天的数据
        :param historical_data_list: 历史数据列表
        :param days: 要获取的天数
        :return: 前几天的数据列表
        """
        if len(historical_data_list) >= days:
            return historical_data_list[-days:]  # 返回前几天的数据（不排除今天的数据）
        return None  # 如果历史数据列表为空或没有足够的数据，返回None


# 使用示例
if __name__ == "__main__":
    # 创建 HistoricalStockDataFetcher 实例
    fetcher = HistoricalStockDataFetcher()

    # 设置参数
    symbol = "000001"  # 股票代码（示例）
    start_date = "20200101"
    end_date = "20201231"

    try:
        # 获取历史股票数据
        historical_data = fetcher.fetch_stock_data(symbol, start_date, end_date)
        print(f"成功获取 {symbol} 的历史数据，共 {len(historical_data)} 条记录。")

        # 假设最新价格为150
        latest_price = 150.0

        # 计算振幅
        amplitudes = fetcher.calculate_amplitudes(historical_data, latest_price)
        print(f"{symbol} 的振幅为: {amplitudes}%")

        # 获取最近 5 天的数据
        recent_days = fetcher.get_days_before(historical_data, 5)
        print("最近 5 天的数据如下:")
        for data in recent_days:
            print(data)

    except ValueError as ve:
        print(ve)
    except Exception as e:
        print(f"发生错误: {e}")